import cv2
import numpy as np
import tkinter as tk
from tkinter import filedialog, messagebox

# 初始化全局变量
points = []
image = None

def draw_polygon(event, x, y, flags, param):
    global points
    if event == cv2.EVENT_LBUTTONDOWN:
        points.append((x, y))
        draw_image()

def calculate_grayscale_mean(image, points):
    mask = np.zeros(image.shape[:2], dtype=np.uint8)
    points_array = np.array(points, dtype=np.int32)
    cv2.fillPoly(mask, [points_array], 255)

    # 提取不规则区域的像素值
    masked_values = cv2.bitwise_and(image, image, mask=mask)
    masked_pixels = masked_values[mask == 255]

    # 计算灰度值平均值
    mean_value = cv2.mean(masked_pixels)[0]
    return mean_value

def select_image():
    global image, points
    points = []
    file_path = filedialog.askopenfilename(title="选择图像文件", filetypes=[("图像文件", "*.jpg;*.jpeg;*.png;*.bmp")])
    if file_path:
        image = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), cv2.IMREAD_GRAYSCALE)
        if image is None:
            messagebox.showerror("错误", "图像加载失败")
        else:
            draw_image(fullscreen=True)

def draw_image(fullscreen=False):
    global image, points
    temp_image = image.copy()
    if points:
        cv2.polylines(temp_image, [np.array(points)], isClosed=True, color=(255), thickness=2)

    cv2.imshow('image', temp_image)
    if fullscreen:
        cv2.setWindowProperty('image', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

def calculate_and_show():
    global image, points
    if len(points) < 3:
        messagebox.showwarning("警告", "需要至少三个点来描绘不规则区域")
        return
    mean_gray_value = calculate_grayscale_mean(image, points)
    messagebox.showinfo("结果", f"不规则区域的灰度值平均值: {mean_gray_value}")

def main():
    global image
    # 创建主窗口
    root = tk.Tk()
    root.title("灰度值平均值计算器")

    # 添加按钮
    btn_select = tk.Button(root, text="选择图像", command=select_image)
    btn_select.pack(side=tk.LEFT, padx=5, pady=5)

    btn_calculate = tk.Button(root, text="计算灰度值平均值", command=calculate_and_show)
    btn_calculate.pack(side=tk.LEFT, padx=5, pady=5)

    btn_exit = tk.Button(root, text="退出", command=root.quit)
    btn_exit.pack(side=tk.RIGHT, padx=5, pady=5)

    # 设置OpenCV窗口
    cv2.namedWindow('image', cv2.WND_PROP_FULLSCREEN)
    cv2.setMouseCallback('image', draw_polygon)

    # 主循环
    root.mainloop()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()
